/*
 * @FilePath     : /study_code/vue/principle2.js
 * @Description  : Object.defineProperty() api 重写 对象的getter, setter 函数
 * @Date         : 2025-04-29 16:59:14
 * @Author       : Fang YingGui
 * @LastEditors  : fangyinggui 18715384437@163.com
 * @LastEditTime : 2025-04-29 17:00:19
 */
/**
 * @brief: 判断 obj 是否是对象
 * @param {object} obj 被判断的对象
 * @return {boolean}
 */
function isObject(obj) {
  return typeof obj === 'object' && !Array.isArray(obj) && obj !== undefined && obj !== null
}

/**
 * @brief: 重写对象 的 getter & setter 函数
 * !为对象的每个属性设置，都添加上 getter & setter 取值&存值函数
 * @param {*} obj 被重写的对象
 * @return {*}
 */
function convert(obj) {
  if (!isObject(obj)) {
    throw new Error('参数不为对象')
  }
  Object.keys(obj).forEach(key => {
    let tempValue = obj[key] // 动态 - 某个键对应的键值
    // 为属性定义 getter & setter
    Object.defineProperty(obj, key, {
      get() {
        console.log(`获取属性${key}，值为${tempValue}`)
        return tempValue
      },
      set(newValue) {
        tempValue = newValue
        console.log(`设置属性${key}，值为${tempValue}`)
      },
    })
  })
}

// 调用函数
const obj = { foo: 123 }
convert(obj)
console.log('重写对象的 set, get 后', obj) // { foo: 234 }

console.log(obj.foo)
/*
赋值前，取值：
'获取属性foo，值为123'
123
*/

obj.foo = 234
console.log(obj.foo)
/*
赋值后
'设置属性foo，值为234'，
再获取值：
'获取属性foo，值为234'
'234'
*/
